home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / std / c++ / 184 < prev    next >
Encoding:
Text File  |  1996-08-06  |  6.4 KB  |  175 lines

  1. Path: engnews1.Eng.Sun.COM!taumet!clamage
  2. From: gregor@netcom.com (Greg Colvin)
  3. Newsgroups: comp.std.c++
  4. Subject: Cleaning auto_ptr copy semantics.
  5. Date: 26 Jan 1996 15:47:28 GMT
  6. Organization: Netcom Online Communications Services (408-241-9760 login: guest)
  7. Approved: clamage@eng.sun.com (comp.std.c++)
  8. Message-ID: <gregorDLrrun.K2x@netcom.com>
  9. NNTP-Posting-Host: taumet.eng.sun.com
  10. Content-Type: text
  11. Apparently-To: comp-std-c++@uunet.uu.net
  12. Content-Length: 5863
  13. X-Lines: 154
  14. Originator: clamage@taumet
  15.  
  16. Our working paper's auto_ptr (20.4.5) specifies a non-const copy constructor 
  17. and assignment operator.  This specification makes functions that return 
  18. auto_ptr less useful than I intended, due to a language restriction on
  19. modifying temporaries.  Since changing the language specification seems not
  20. to be an option, a change to auto_ptr is in order.  
  21.  
  22. The smallest change I can see that preserves the semantics of strict 
  23. ownership is to separate the concepts of "holding a pointer" and "owning 
  24. an object", so that more than one auto_ptr can hold a pointer to an object,
  25. but only one auto_ptr can own the object.  
  26.  
  27. Note that only the held pointer is directly accessible; which auto_ptr 
  28. owns an object is observable only via the side effects of destructor calls.
  29. Thus providing const arguments to the copy constructor and assignment 
  30. operator and making release() a const function seem to me a reasonable 
  31. case of "logical constness". 
  32.  
  33. Note also that reset() must go, since the idiom p.reset(q.release()) 
  34. cannot safely transfer ownership.  I would happily remove get() as well, 
  35. since its primary use may turn out to be leaking pointers.
  36.  
  37. A simple implementation makes the semantics clear:
  38.  
  39.    template<class X> class auto_ptr {
  40.       X* px;
  41.       mutable bool owner;
  42.    public:
  43.       explicit auto_ptr(X* p=0) : px(p), owner(true) {}
  44.       template<class Y>
  45.          auto_ptr(const auto_ptr<Y>& r) : px(r.release()), owner(true) {}
  46.       template<class Y>
  47.          auto_ptr& operator=(const auto_ptr<Y>& r) {
  48.             if (&r != this) {
  49.                if (owner) delete px; else owner = true;
  50.                px = r.release();
  51.             }
  52.             return *this;
  53.          }
  54.       ~auto_ptr() { if (owner) delete px; }
  55.  
  56.       X& operator*()  const { return *px; }
  57.       X* operator->() const { return px; }
  58.       X* get()        const { return px; }
  59.       X* release()    const { owner = false; return px; }
  60.    };
  61.  
  62. This implementation is slightly bigger (one bool) and slightly slower
  63. (two extra tests and two and one-half extra assignments across eight
  64. functions) than the comparable implementation of the WP semantics.  On
  65. some hardware it might make sense to save space at the cost of masking 
  66. off the ownership bit or trapping memory hardware interrupts.
  67.  
  68. The changed Working Paper text I plan to propose at Scotts Valley is:
  69.  
  70.  
  71. 20.4.5  Template class auto_ptr                          [lib.auto.ptr]
  72.  
  73. Template auto_ptr holds onto a pointer to an object obtained via new 
  74. and deletes that object when it is the owner of that object and it 
  75. itself is destroyed (such as when leaving block scope 6.7).
  76.  
  77. namespace std {
  78.   template<class X> class auto_ptr {
  79.   public:
  80.   // 20.4.5.1 construct/copy/destroy:
  81.     explicit auto_ptr(X* p=0);
  82.     template<class Y> auto_ptr(const auto_ptr<Y>&);                     |
  83.     template<class Y> auto_ptr& operator=(const auto_ptr<Y>&);          |
  84.     ~auto_ptr();
  85.   // 20.4.5.2 members:
  86.     X& operator*() const;
  87.     X* operator->() const;
  88.     X* get() const;                                                      ?
  89.     X* release() const;                                                 | 
  90.                                                                         |
  91.   };
  92. }
  93.  
  94. The auto_ptr provides a semantics of strict ownership.  After initial   |
  95. construction an auto_ptr owns the object it holds a pointer to.  An     |
  96. object may be safely owned by only one auto_ptr, so copying an auto_ptr |
  97. copies the pointer and transfers ownership to the destination.          |
  98.  
  99.  
  100. 20.4.5.1  auto_ptr constructors                     [lib.auto.ptr.cons]
  101.  
  102. explicit auto_ptr(X* p = 0);
  103.  
  104.   Requires:  
  105.     p points to an object of type X or a class derived from X for which 
  106.     delete p is defined and accessible, or else p is a null pointer.
  107.   Postconditions:
  108.     *this holds the pointer p.                                          |
  109.     *this is the owner of the object **this.                            |
  110.  
  111. template<class Y> auto_ptr(const auto_ptr<Y>& a);                       |
  112.  
  113.   Requires:  
  114.     Y is type X or a class derived from X for which delete(Y*) is 
  115.     defined and accessible.
  116.   Effects:  
  117.     Calls a.release().
  118.   Postconditions:  
  119.     *this holds the pointer returned from a.release().                  |
  120.     *this is the owner of the object **this.                            |
  121.  
  122. template<class Y> auto_ptr<X>& operator=(const auto_ptr<Y>& a);         |
  123.  
  124.   Requires:
  125.     Y is type X or a class derived from X for which delete(Y*) is 
  126.     defined and accessible.
  127.   Effects:  
  128.     If *this is the owner of **this and this != &a then delete &**this. |
  129.     Calls a.release().
  130.   Returns: 
  131.     *this.
  132.   Postconditions: 
  133.     *this holds the pointer returned from a.release().                  |
  134.     *this is the owner of the object **this.                            |
  135.  
  136. ~auto_ptr();
  137.  
  138.   Effects:
  139.     If *this is the owner of **this then delete &**this.                |
  140.  
  141.  
  142. 20.4.5.2  auto_ptr members                       [lib.auto.ptr.members]
  143.  
  144. X& operator*() const;
  145.  
  146.   Requires:
  147.     get() != 0
  148.   Returns:
  149.     A reference to the object pointed to by the pointer held by *this.  |
  150.  
  151. X* operator->() const;
  152.  
  153.   Returns:
  154.     The pointer held by *this.                                          |
  155.  
  156. X* get() const;                                                          ?
  157.                                                                          ?
  158.   Returns:                                                               ?
  159.     The pointer held by *this.                                          |?
  160.  
  161. X* release() const;                                                     |
  162.  
  163.   Returns:
  164.     The pointer held by *this.                                          |
  165.   Postcondition:
  166.     *this is not the owner of the object **this.                        |
  167.  
  168.  
  169.                                                                         |
  170.  
  171. [ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  172.   Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  173.   is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
  174.  
  175.